package com.hcms.common.util;

import cn.hutool.json.JSONObject;
import cn.hutool.jwt.JWT;
import cn.hutool.jwt.JWTUtil;
import com.hcms.common.config.CmsJwtProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.Map;

/**
 * JwtToken生成的工具类
 */
public class JwtTokenUtil {
    private static final Logger logger = LoggerFactory.getLogger(JwtTokenUtil.class);

    private static final String KEY_NAME = "sub";
    private static final String KEY_EXP = "exp";

    private static CmsJwtProperties jwtConfig;

    @Autowired
    private void jwtConfig(CmsJwtProperties config) {
        jwtConfig = config;
    }

    /**
     * 根据用户信息生成token
     */
    public static String createToken(String username) {
        logger.info("Run createToken(), username={}", username);
        Map<String, Object> payload = new HashMap<>();
        payload.put(KEY_NAME, username);
        payload.put(KEY_EXP, System.currentTimeMillis() + jwtConfig.getExpiration() * 1000);
        return JWTUtil.createToken(payload, jwtConfig.getTokenSecret().getBytes());
    }

    /**
     * 验证token是否还有效
     *
     * @param token 客户端传入的token
     */
    public boolean verify(String token) {
        logger.info("Run verify()");
        JSONObject payloads = getPayloads(token);
        return payloads != null;
    }


    /**
     * 从token中获取登录用户名
     */
    public String getUserNameFromToken(String token) {
        logger.info("Run getUserNameFromToken()");
        String username = null;
        JSONObject payloads = getPayloads(token);
        if (payloads != null) {
            username = payloads.get(KEY_NAME, String.class);
            logger.info("Get username success, username={}", username);
        }
        return username;
    }

    /**
     * 刷新token
     *
     * @param oldToken
     * @return
     */
    public String refreshToken(String oldToken) {
        logger.info("Run refreshToken()");
        JSONObject payloads = getPayloads(oldToken);
        if (payloads != null) {
            String username = payloads.get(KEY_NAME, String.class);
            return createToken(username);
        }
        return null;
    }

    /**
     * 校验获取token中数据
     *
     * @param token
     * @return
     */
    private JSONObject getPayloads(String token) {
        logger.info("Run getPayloads()");
        boolean verify = JWTUtil.verify(token, jwtConfig.getTokenSecret().getBytes());
        if (verify) {
            logger.info("Determines whether the token is expired");
            JWT jwt = JWTUtil.parseToken(token);
            JSONObject payloads = jwt.getPayloads();
            Long exp = payloads.get(KEY_EXP, Long.class);
            if (System.currentTimeMillis() < exp) {
                logger.info("The token is not expired");
                return payloads;
            }
        }
        logger.error("The token has expired");
        return null;
    }
}
